﻿using Bilibili.Common.Api;
using Bilibili.Model.Common;
using Bilibili.WebClient.Common;
using PCLUntils.Objects;
using System;
using System.Collections.Generic;
using System.Text;

namespace Bilibili.WebClient
{
    internal sealed class ApiInfo : IApiInfo
    {
        public ApiInfo(string original, bool needKey)
        {
            Original = original;
            NeedKey = needKey;
        }
        public ApiInfo(string original, bool needKey, bool msTimeStamp)
        {
            Original = original;
            NeedKey = needKey;
            MsTimeStamp = msTimeStamp;
        }
        public ApiInfo(string original, bool needKey, ApiKeyInfo keyInfo)
        {
            Original = original;
            NeedKey = needKey;
            ApiKeyInfo = keyInfo;
        }
        public ApiInfo(string original, bool needKey, ApiKeyInfo keyInfo, bool msTimeStamp)
        {
            Original = original;
            NeedKey = needKey;
            ApiKeyInfo = keyInfo;
            MsTimeStamp = msTimeStamp;
        }
        public ApiInfo(string original, bool needKey, string buildVer)
        {
            Original = original;
            BuildVer = buildVer;
            NeedKey = needKey;
        }
        public ApiInfo(string original, string conditions, bool needKey)
        {
            Original = original;
            NeedKey = needKey;
            Conditions = conditions;
        }
        public ApiInfo(bool needSignKey, string original, string conditions)
        {
            Original = original;
            Conditions = conditions;
            NeedSignKey = needSignKey;
        }
        public ApiInfo(string original, string conditions, bool needKey, bool msTimeStamp)
        {
            Original = original;
            NeedKey = needKey;
            Conditions = conditions;
            MsTimeStamp = msTimeStamp;
        }
        public ApiInfo(string original, string conditions, bool needKey, string buildVer)
        {
            Original = original;
            NeedKey = needKey;
            BuildVer = buildVer;
            Conditions = conditions;
        }
        public ApiInfo(string original, string conditions, bool needKey, ApiKeyInfo keyInfo)
        {
            Original = original;
            NeedKey = needKey;
            ApiKeyInfo = keyInfo;
            Conditions = conditions;
        }
        public ApiInfo(string original, string conditions, bool needKey, ApiKeyInfo keyInfo, bool msTimeStamp)
        {
            Original = original;
            NeedKey = needKey;
            ApiKeyInfo = keyInfo;
            Conditions = conditions;
            MsTimeStamp = msTimeStamp;
        }
        public bool NeedKey { get; set; }
        public string Original { get; set; }
        public string Conditions { get; set; }
        public bool MsTimeStamp { get; set; }
        public bool NeedSignKey { get; set; } = true;
        public string BuildVer { get; set; } = ApiProviderBase.Build5;
        public ApiKeyInfo ApiKeyInfo { get; set; } = ApiProvider.Instance.AndroidKey;
        public Uri ToUri()
        {
            return new Uri(ToString());
        }
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder(Original);
            var pairs = new Dictionary<string, object>();
            if (NeedSignKey)
                pairs.Add("appkey", ApiKeyInfo.Appkey);
            if (NeedSignKey || (NeedKey && ApiProvider.Instance.IsLogin))
                pairs.Add("access_key", ApiProvider.Instance.AccessKey);
            if (ApiKeyInfo != ApiProvider.Instance.WebVideoKey && NeedSignKey)
            {
                pairs.Add("build", BuildVer);
                pairs.Add("device", "android");
                pairs.Add("mobi_app", "android");
                pairs.Add("platform", "android");
            }
            if (!MsTimeStamp)
                pairs.Add("ts", ApiProvider.Instance.TimeSpanSeconds);
            else
                pairs.Add("ts", ApiProvider.Instance.TimeSpanMilliseconds);
            stringBuilder.Append("?");
            foreach (var pair in pairs)
                stringBuilder.Append($"{pair.Key}={pair.Value}&");
            if (Conditions.IsNotEmpty() && Conditions.StartsWith("&"))
                stringBuilder.Length -= 1;
            stringBuilder.Append(Conditions);
            var requestUrl = stringBuilder.ToString();
            return $"{requestUrl}&sign={ApiProvider.Instance.GetSign(requestUrl, ApiKeyInfo)}";
        }
    }
}